#ifndef IO_HANDLE_H_
#define IO_HANDLE_H_

#ifdef __cplusplus
extern "C"
{
#endif

#include "stdint.h"

	uint8_t ad_io_creat(uint8_t sample_old, uint16_t ad_true, uint16_t ad_false, uint16_t ad_now);

	typedef struct
	{
		void (*en)(void);
		void (*dis)(void);
		void (*tog)(void);
		uint8_t (*out_st)(void);
	} out_obj_type;

	typedef struct
	{
		uint32_t key_val;
		
		void (*press_down)(void);
		
		void (*press_keep)(void);
		
		void (*press_release)(void);
	} key_opt_type;

	typedef struct
	{
		void (*key_down_any)(void);
		
		void (*key_keep_any)(void);
		
		const key_opt_type *key_obj;
		
		void (*key_release_any)(void);
		
		void (*key_idle)(void);
	} key_api_type;

	typedef struct
	{
		uint8_t read_flt_cnt;	 
		uint8_t b_first_key;	 
		uint8_t b_do_none_rls;	 
		uint8_t series_space_sv; 
		uint8_t serial_cnt;		 
		uint16_t found_time_cnt; 
		uint16_t lost_time_cnt;	 
		uint16_t keep_time_cnt;	 
		uint32_t val;			 
		uint32_t old;			 
		uint32_t mixed_val;		 
		uint32_t edge;			 
		uint32_t found_edge;	 
		uint32_t lost_edge;		 
		uint32_t serial_edge;	 
		uint32_t read;			 
		uint32_t read_old;		 
		const key_api_type *api; 
	} key_type;
	void key_st_handle(key_type *key, uint8_t time_pulse);
	void key_st_sample(key_type *key, uint8_t flt_sv, uint32_t key_read);
#define key_st_isr key_st_sample

	typedef struct
	{
		uint8_t space_sv;  
		uint8_t serial_sv; 

		uint8_t serial_cnt;
		uint8_t key_old;
		uint8_t multi_click_out; 
		uint8_t edge_found;		 
		uint8_t edge_lost;		 
		uint16_t st_keep_cnt;
	} key_click_type;

	uint8_t key_click_handle(key_click_type *obj, uint8_t key_now, uint8_t pulse);

	typedef struct
	{
		uint8_t time_pulse;	  
		uint8_t sample_pulse; 
		uint8_t val;
		uint8_t old;
		uint8_t found_edge;
		uint8_t lost_edge;
		uint8_t sample_old;
		uint8_t sample_keep_cnt; 
		uint32_t found_time_cnt; 
		uint32_t lost_time_cnt;	 
	} in_switch_st_type;

	typedef struct
	{
		struct
		{
			uint8_t time_pulse : 1;	  
			uint8_t sample_pulse : 1; 
			uint8_t val : 1;
			uint8_t old : 1;
			uint8_t found_edge : 1;
			uint8_t lost_edge : 1;
			uint8_t sample_old : 1;
		} st;
		uint8_t sample_keep_cnt; 
		uint16_t found_time_cnt; 
		uint16_t lost_time_cnt;	 
	} simp_switch_st_type;		 

	typedef struct
	{
		uint8_t time_pulse; 
		uint8_t old;
		uint8_t enable_edge;
		uint8_t disable_edge;
		uint32_t enable_time_cnt;  
		uint32_t disable_time_cnt; 
	} out_st_type;

	typedef struct
	{
		uint8_t out; 
		uint8_t old;
		uint8_t enable_edge;
		uint8_t disable_edge;
		uint32_t enable_time_cnt;  
		uint32_t disable_time_cnt; 
	} out_stv2_type;

	typedef struct
	{
		struct
		{
			uint8_t time_pulse : 1; 
			uint8_t old : 1;
			uint8_t enable_edge : 1;
			uint8_t disable_edge : 1;
		} st;
		uint16_t enable_time_cnt;  
		uint16_t disable_time_cnt; 
	} simp_out_st_type;

	void in_switch_handle(in_switch_st_type *swobj, uint8_t sw_now);	 
	void simp_switch_handle(simp_switch_st_type *swobj, uint8_t sw_now); 
	void out_st_handle(out_st_type *obj, uint8_t out_now);				 
	void out_stv2_handle(out_stv2_type *obj, uint8_t time_pulse);		 
	void simp_out_st_handle(simp_out_st_type *obj, uint8_t out_now);	 

	typedef struct
	{
		uint8_t b_clock;			  
		uint8_t b_unti_clock;		  
		uint16_t clock_interval_rl;	  
		uint16_t clock_none_time_cnt; 
		uint16_t high_spd_pulse_cnt;
		uint8_t a_st;
		uint8_t a_old;
		uint8_t b_st;
		uint8_t b_old;
		uint8_t spd_st;				 
		uint16_t clock_interval_val; 
		const uint16_t *high_spd_tm; 
	} rot_key_type;

	void rot_key_handle(rot_key_type *key, uint8_t a, uint8_t b);  
	void rot_ekey_handle(rot_key_type *key, uint8_t a, uint8_t b); 
	uint8_t rot_key_spd_check(rot_key_type *key);
	
	typedef struct
	{
		uint8_t st;		
		int8_t flt_cnt; 
	} io_flt_type;

	typedef struct
	{
		struct
		{
			uint8_t val : 1; 
			uint8_t old : 1;
			uint8_t edge : 1;
			uint8_t edge_found : 1;
			uint8_t edge_lost : 1;
		} st;

		int8_t flt_cnt; 
	} io_flt_edge_type;

	typedef struct
	{
		struct
		{
			uint8_t val : 1; 
			uint8_t old : 1;
			uint8_t edge : 1;
			uint8_t edge_found : 1;
			uint8_t edge_lost : 1;
			uint8_t pulse_sample : 1; 
			uint8_t pulse_time : 1;	  
		} st;

		int8_t flt_cnt; 
		uint16_t found_time_cnt;
		uint16_t lost_time_cnt;
	} io_flt_ext_type;

	typedef struct
	{
		struct
		{
			uint8_t val : 1; 
			uint8_t old : 1;
			uint8_t edge : 1;
			uint8_t edge_found : 1;
			uint8_t edge_lost : 1;
		} st;

		int8_t flt_cnt; 
		uint16_t found_time_cnt;
		uint16_t lost_time_cnt;
	} io_flt_extv2_type;

	typedef struct
	{
		struct
		{
			uint8_t val : 1; 
			uint8_t old : 1;
			uint8_t edge : 1;
			uint8_t edge_found : 1;
			uint8_t edge_lost : 1;
		} st;
		uint8_t lost_keep_sv, found_keep_sv; 
		uint8_t lost_keep_cnt, found_keep_cnt;
		int8_t flt_cnt; 
		uint16_t found_time_cnt;
		uint16_t lost_time_cnt;
	} io_flt_extv3_type;

	uint8_t io_flt(io_flt_type *io_obj, int8_t flt_sv, uint8_t st_now); 
	uint8_t io_flt_edge(io_flt_edge_type *io_obj, uint8_t flt_pulse, int8_t flt_sv, uint8_t st_now);
	uint8_t io_flt_ext(io_flt_ext_type *io_obj, int8_t flt_sv, uint8_t st_now);											   
	uint8_t io_flt_extv2(io_flt_extv2_type *io_obj, uint8_t flt_pulse, uint8_t time_pulse, int8_t flt_sv, uint8_t st_now); 
	uint8_t io_flt_extv3(io_flt_extv3_type *io_obj, uint8_t flt_pulse, uint8_t time_pulse, int8_t flt_sv, uint8_t st_now); 

	typedef struct
	{
		uint8_t val : 1;
		uint8_t val_old : 1;
		uint8_t edge : 1;
		uint8_t edge_found : 1;
		uint8_t edge_lost : 1;
		uint16_t keep_cnt;
		uint32_t stlist;
	} io_stcnt_flt_type;

	typedef struct
	{
		uint8_t val : 1;
		uint8_t val_old : 1;
		uint8_t edge : 1;
		uint8_t edge_found : 1;
		uint8_t edge_lost : 1;
		uint16_t keep_cnt;
		uint32_t stlist[4];
	} io_mstcnt_flt_type;

	void io_stcnt_flt_sample(io_stcnt_flt_type *obj, uint8_t st_now);
	uint8_t io_stcnt_flt_handle(io_stcnt_flt_type *obj, uint8_t tm_pulse, uint8_t flt_sv, uint8_t en_sv, uint8_t dis_sv);
	uint8_t io_stcnt_flt(io_stcnt_flt_type *obj, uint8_t flt_pulse, uint8_t flt_sv, uint8_t en_sv, uint8_t dis_sv, uint8_t st_now);

	void io_mstcnt_flt_sample(io_mstcnt_flt_type *obj, uint8_t st_now);
	uint8_t io_mstcnt_flt_handle(io_mstcnt_flt_type *obj, uint8_t tm_pulse, uint8_t flt_sv, uint8_t en_sv, uint8_t dis_sv);
	uint8_t io_mstcnt_flt(io_mstcnt_flt_type *obj, uint8_t flt_pulse, uint8_t flt_sv, uint8_t en_sv, uint8_t dis_sv, uint8_t st_now);

	typedef struct
	{
		uint8_t val;
		uint8_t val_old;
		uint8_t read_old;
		uint8_t edge;
		uint8_t edge_found;
		uint8_t edge_lost;
		uint8_t flt_cnt;
	} io8_flt_type;

	typedef struct
	{
		uint16_t val;
		uint16_t val_old;
		uint16_t read_old;
		uint16_t edge;
		uint16_t edge_found;
		uint16_t edge_lost;
		uint8_t flt_cnt;
	} io16_flt_type;

	typedef struct
	{
		uint32_t val;
		uint32_t val_old;
		uint32_t read_old;
		uint32_t edge;
		uint32_t edge_found;
		uint32_t edge_lost;
		uint8_t flt_cnt;
	} io32_flt_type;

	void io8_flt(io8_flt_type *io_obj, uint8_t flt_sv, uint8_t read_now, uint8_t pulse);
	void io16_flt(io16_flt_type *io_obj, uint8_t flt_sv, uint16_t read_now, uint8_t pulse);
	void io32_flt(io32_flt_type *io_obj, uint8_t flt_sv, uint32_t read_now, uint8_t pulse);

	typedef struct
	{
		uint8_t val;
		uint8_t read_old;
		uint8_t flt_cnt;
	} io8_simp_flt_type;

	typedef struct
	{
		uint16_t val;
		uint16_t read_old;
		uint8_t flt_cnt;
	} io16_simp_flt_type;

	typedef struct
	{
		uint32_t val;
		uint32_t read_old;
		uint8_t flt_cnt;
	} io32_simp_flt_type;

	void io8_simp_flt(io8_simp_flt_type *io_obj, uint8_t flt_sv, uint8_t read_now);
	void io16_simp_flt(io16_simp_flt_type *io_obj, uint8_t flt_sv, uint16_t read_now);
	void io32_simp_flt(io32_simp_flt_type *io_obj, uint8_t flt_sv, uint32_t read_now);

	typedef struct
	{
		uint8_t val;
		uint8_t val_old;
		uint8_t edge_found;
		uint8_t edge_lost;
		uint8_t read_old[8];
	} io8_sig_flt_type;
	typedef struct
	{
		uint16_t val;
		uint16_t val_old;
		uint16_t edge_found;
		uint16_t edge_lost;
		uint16_t read_old[8];
	} io16_sig_flt_type;
	typedef struct
	{
		uint32_t val;
		uint32_t val_old;
		uint32_t edge_found;
		uint32_t edge_lost;
		uint32_t read_old[8];
	} io32_sig_flt_type;
	void io8_sig_flt(io8_sig_flt_type *io_obj, uint8_t flt_sv, uint8_t read_now, uint8_t pulse);
	void io16_sig_flt(io16_sig_flt_type *io_obj, uint8_t flt_sv, uint16_t read_now, uint8_t pulse);
	void io32_sig_flt(io32_sig_flt_type *io_obj, uint8_t flt_sv, uint32_t read_now, uint8_t pulse);

	typedef struct
	{
		uint8_t sig;
		uint8_t sig_old;
		uint8_t edge, edge_found, edge_lost;
		uint16_t found_time_cnt;
		uint16_t lost_time_cnt;
	} io_signal_type;
	uint8_t io_signal_info_handle(io_signal_type *io_obj, uint8_t time_pulse, uint8_t sig_new);

	typedef struct
	{
		uint8_t st;			 
		int8_t flt_cnt;		 
		uint16_t period_cnt; 
		uint16_t active_cnt; 
		uint8_t st_old;		 

		uint16_t period_sv; 
		uint16_t active_sv; 
		int8_t flt_sv;		
		uint8_t flt_pulse;	
		uint8_t time_pulse; 

		uint8_t found_edge, lost_edge; 
		uint16_t found_time;		   
		uint16_t lost_time;			   
	} discont_in_flt_type;

	uint8_t discont_in_flt(discont_in_flt_type *obj, uint8_t in_val);

	typedef struct
	{
		uint8_t out;	   
		uint8_t en_edge;   
		uint8_t dis_edge;  
		uint8_t en_req;	   
		uint8_t dis_req;   
		uint32_t en_time;  
		uint32_t dis_time; 
	} out_sw_type;
	;
	
	uint8_t out_sw_manage(out_sw_type *out_obj, uint32_t en_time_sv, uint32_t dis_time_sv, uint8_t pulse);

	typedef struct
	{
		uint8_t out;	   
		uint8_t err;	   
		uint8_t comp;	   
		uint16_t en_time;  
		uint16_t dly_time; 
	} wt_add_type;
	;

	uint8_t wt_add_manage(wt_add_type *out_obj, uint8_t wt_st, uint16_t ot_time_sv, uint16_t dly_time_sv, uint8_t pulse);

	typedef struct
	{
		uint8_t out0;			  
		uint8_t out1;			  
		uint8_t mode;			  
		uint8_t out_sel;		  
		int32_t out0_en_time;	  
		int32_t out0_dis_time;	  
		int32_t out1_en_time;	  
		int32_t out1_dis_time;	  
		int32_t delay_cnt;		  
		int32_t dev_off_min_time; 
	} dev_double_sw_type;

	void dev_double_sw(dev_double_sw_type *dev, int32_t switch_time_set, int32_t switch_time_befor, uint8_t pulse);

	typedef struct
	{
		uint8_t st;		  
		uint8_t st_start; 
		uint32_t cct_set; 
		uint32_t nct_set; 
		uint32_t sot_set; 
		uint32_t spd_now; 
		uint32_t cnt;	  
	} nc_cc_sw_type;

#define C_ST_NC_STOP 0
#define C_ST_CC_RUN 1
#define C_ST_CC_STOP 2
#define C_ST_NC_RUN 3

	uint8_t nc_cc_sw_handle(nc_cc_sw_type *obj, uint8_t en, uint8_t pulse);

	typedef struct
	{
		uint32_t spd_now;		   
		uint32_t spd_set;		   
		uint32_t spd_out;		   
		uint32_t spd_up;		   
		uint32_t spd_dn;		   
		uint32_t spd_rl;		   
		uint8_t pwm_out_under_min; 
	} spd_inc_type;

	uint32_t spd_inc_handle(spd_inc_type *obj, uint8_t pulse);

	typedef struct
	{
		uint8_t micro_req;	 
		uint8_t short_req;	 
		uint8_t mid_req;	 
		uint8_t long_req;	 
		uint8_t auto_req;	 
		uint8_t auto_period; 
		uint8_t auto_duty;	 
		uint8_t pulse_cnt;	 
		uint8_t b_beep_st;	 
	} beep_notice_type;

	void beep_handle(beep_notice_type *obj, uint8_t bpulse);
	void beep_clear(beep_notice_type *obj);
	void beep_auto_req(beep_notice_type *obj, uint8_t req_cnt, uint8_t period, uint8_t duty);
	void beep_micro_req(beep_notice_type *obj, uint8_t req_cnt);
	void beep_short_req(beep_notice_type *obj, uint8_t req_cnt);
	void beep_mid_req(beep_notice_type *obj, uint8_t req_cnt);
	void beep_long_req(beep_notice_type *obj, uint8_t req_cnt);

	typedef struct
	{
		uint8_t run_st;		  
		uint8_t out;		  
		int8_t dir;			  
		uint8_t dir_keep_cnt; 
		uint8_t dir_keep_sv;  

		int16_t sv;			
		int16_t pv;			
		int16_t en_offset;	
		int16_t dis_offset; 
		int16_t dir_zone;	
		int16_t min;		
		int16_t max;		
	} comp_out_type;

	uint8_t comp_out_handle(comp_out_type *obj, uint8_t dir_adj_pulse);		
	uint8_t comp_out_nev_handle(comp_out_type *obj, uint8_t dir_adj_pulse); 

	typedef struct
	{
		uint8_t req;		   
		uint8_t condition;	   
		uint8_t st_back;	   
		uint8_t exe_max;	   
		uint16_t exe_time_sv;  
		uint16_t idle_time_sv; 

		uint16_t exe_time_cnt;	
		uint16_t idle_time_cnt; 
		uint8_t exe_st;			
		uint8_t err;			
		uint8_t out;			
	} out_exe_type;

	void out_exe_hadle(out_exe_type *obj, uint8_t pulse);

#ifdef __cplusplus
}
#endif

#endif 
